#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "esp_ota_ops.h"
#include "esp_flash_partitions.h"
#include "esp_partition.h"
#include "DriverOTA.h"


OTAInfoType g_typeOTAInfo;

/* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
esp_ota_handle_t st_ota_handle_update = 0 ;

const esp_partition_t *st_partition_update = NULL;
const esp_partition_t *st_partition_running = NULL;

esp_app_desc_t st_app_desc_running;


/* 固件数据写入 */
int8_t cOTADatasWrite(uint32_t uiAddr, void *pvDatas, int32_t iLength)
{
    if(st_ota_handle_update == 0)
        return 1;

    return esp_ota_write_with_offset(st_ota_handle_update, pvDatas, iLength, uiAddr);
}

int8_t cOTAStart(void)
{
    if(st_partition_update == NULL)
        return 1;

    if(st_partition_update == st_partition_running)
        return 2;

    return esp_ota_begin(st_partition_update, OTA_WITH_SEQUENTIAL_WRITES, &st_ota_handle_update);
}

int8_t cOTAStop(void)
{
    if(esp_ota_end(st_ota_handle_update) != ESP_OK)
        return 1;

    if(esp_ota_set_boot_partition(st_partition_update) != ESP_OK)
        return 2;

    return 0;
}

int8_t cOTAError(void)
{
    return esp_ota_abort(st_ota_handle_update);
}

int8_t cOTAInfoUpdate(void)
{
    return esp_ota_get_partition_description(st_partition_running, &st_app_desc_running);
}

int8_t cOTAInit(void)
{
    st_partition_running = esp_ota_get_running_partition();

    cOTAInfoUpdate();

    if((st_partition_update = esp_ota_get_next_update_partition(NULL)) == NULL)
        return 1;

    return 0;
}

OTAInfoType *ptypeOTAInfoGet(void)
{
    return &g_typeOTAInfo;
}
